package cn.com.rexen.rplus.security;

import cn.com.rexen.rplus.core.execption.EmptyValueException;
import cn.com.rexen.rplus.core.service.impl.BaseServiceImpl;
import cn.com.rexen.rplus.core.utils.StringUtils;
import cn.com.rexen.rplus.sa.entity.Role;
import cn.com.rexen.rplus.sa.entity.User;
import cn.com.rexen.rplus.sa.service.PermissionService;
import cn.com.rexen.rplus.sa.service.RoleService;
import cn.com.rexen.rplus.sa.service.UserService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 用户认证自定义实现类 .
 *
 * @author libo
 * @version 1.0.0
 */
@Service(value = "appUserDetailsService")
public class AppUserDetailsService extends BaseServiceImpl<cn.com.rexen.rplus.sa.entity.User> implements
        org.springframework.security.core.userdetails.UserDetailsService {
    /**
     * 日志.
     */
    private final Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 角色服务类.
     */
    @Autowired
    private RoleService roleService;

    /**
     * 用户服务类.
     */
    @Autowired
    private UserService userService;

    /**
     * 权限服务类.
     */
    @Autowired
    private PermissionService permissionService;

    /**
     * 根据用户名获取用户信息.
     *
     * @param userName 用户编号.
     * @return UserDetails.
     * @throws UsernameNotFoundException .
     * @throws DataAccessException       .
     */
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
        if (StringUtils.isEmpty(userName)) {
            throw new IllegalArgumentException("登录名为空.");
        }
        cn.com.rexen.rplus.sa.entity.User user = null;
        try{
            user = loadUserByUserName(userName);
        }catch(Exception e){
            e.printStackTrace();
            throw new UsernameNotFoundException("用户不存在.");
        }

        if (user != null) {
            Set dbAuthsSet = new HashSet();
            dbAuthsSet.addAll(loadUserAuthorities(user.getId()));
            List<GrantedAuthority> dbAuths = new ArrayList(dbAuthsSet);
            logger.debug("authoerities ={}", dbAuths);
            //            if (dbAuths.size() == 0) {
            //                throw new UsernameNotFoundException(
            //                        "User {} has no GrantedAuthority", userName);
            //            }
            return createUserDetails(userName, user, dbAuths);
        } else {
            logger.error("用户 {} 不存在.", userName);
            throw new UsernameNotFoundException("用户不存在.");
        }
    }

    /**
     * 创建用户信息.
     *
     * @param username            用户名.
     * @param user                用户对象.
     * @param combinedAuthorities .
     * @return UserDetails.
     */
    private UserDetails createUserDetails(String username, cn.com.rexen.rplus.sa.entity.User user,
                                          List<GrantedAuthority> combinedAuthorities) {
        String returnUsername = user.getId();
        return new org.springframework.security.core.userdetails.User(returnUsername, user.getPassword(), true, true,
                true, true, combinedAuthorities);
    }

    /**
     * 查询用户权限.
     *
     * @param userName 用户名.
     * @return List.
     */
    private List loadUserAuthorities(String userName) {
        logger.debug("loadUserAuthorities by userId {}", userName);
        // 查询用户所属角色
        List<Role> roleList = roleService.getRoleByUserId(userName);
        if (roleList == null || roleList.size() == 0) {
            throw new EmptyValueException(String.format("用户  %1s 没有指定角色，不能进行登录.", userName));
        }
        logger.debug("user:{},roles:{}", userName, roleList);
        //        // 根据角色查询权限
        //        Set<Permission> role_permission = permissionService.getPermissionByRoles(roleList);
        //        if (role_permission == null || 0 == role_permission.size()) {
        //            logger.warn("roles :{} has no GrantedAuthority", roleList);
        //            return null;
        //        }
        List auList = new ArrayList(roleList.size());
        for (Role role : roleList) {
            SimpleGrantedAuthority ga = new SimpleGrantedAuthority(role.getId());
            auList.add(ga);
        }
        return auList;
    }

    /**
     * 查询用户是否存在.
     *
     * @param name 用户登录名.
     * @return 用户实体.
     */
    private cn.com.rexen.rplus.sa.entity.User loadUserByUserName(String name) {
        User user = userService.validateLoginUser(name);
        return user;
    }

    /**
     * .
     */
    public void reload() {

    }

}
